﻿using System;
using System.Collections.Generic;
using System.Text;

namespace daSyntaxAnalyser.Analysers
{
    // Безопасные объекты и ошибки анализа
    using daBase.Objects;
    using daBase.Objects.Safe;
    using daBase.Objects.AnalysisErrors;

    /// <summary>
    /// Стек синтаксических анализаторов
    /// </summary>
    public class SyntaxAnalysers
    {
        // Стек
        private SafeStack<SyntaxAnalyser> analysers;

        /// <summary>
        /// Конструктор
        /// </summary>
        public SyntaxAnalysers()
        {
            analysers = new SafeStack<SyntaxAnalyser>(() =>
            {
                SyntaxAnalyser analyser = new SyntaxAnalyser();
                analyser.ErrorOccuredEvent += new EventHandler<ErrorArgs>(ErrorOccured);
                return analyser;
            });
        }

        /// <summary>
        /// Сообщение "Произошла ошибка"
        /// </summary>
        public event EventHandler<ErrorArgs> ErrorOccuredEvent;

        /// <summary>
        /// Обработчик события "произошла ошибка"
        /// </summary>
        /// <param name="sender">инициатор события</param>
        /// <param name="e">информация об ошибке</param>
        public void ErrorOccured(object sender, ErrorArgs e)
        {
            if (ErrorOccuredEvent != null)
                ErrorOccuredEvent(sender, e);
        }

        // Одиночка
        private static SyntaxAnalysers instance;

        /// <summary>
        /// Единственный экземпляр стека контроллеров
        /// </summary>
        public static SyntaxAnalysers Instance
        {
            get
            {
                if (instance == null)
                    instance = new SyntaxAnalysers();
                return instance;
            }
        }

        /// <summary>
        /// Вернуть в стек анализатор
        /// </summary>
        /// <param name="Analyser">анализатор</param>
        public void Push(SyntaxAnalyser Analyser)
        {
            Analyser.Reset();
            analysers.Push(Analyser);
        }

        /// <summary>
        /// Взять из стека анализатор
        /// </summary>
        /// <returns>анализатор</returns>
        public SyntaxAnalyser Pop()
        {
            return analysers.Pop();
        }
    }
}
